#!/usr/bin/env python

import sys
import allconsuming.data
import allconsuming.filedac
import pprint
import utils

minReaders = 3

dac = allconsuming.filedac

def readExtraRatings(userName, fileName):
    extraRatings = []
    try:
        f = file(fileName, 'r')
        for line in f:
            (title, itemNumber, rating, tags) = map(str.strip, line.split('|'))
            extra = allconsuming.data.Consumable(userName)
            extra.itemNumber = itemNumber
            extra.consumed = True
            if 'False' == rating:
                extra.worthIt = False
            else:
                extra.worthIt = True
            
            extra.itemTitle = title
            extra.tags = map(str.strip, tags.split(','))
            

            extraRatings.append(extra)
    except:
        return []

    return extraRatings


def readConsumables():
    itemMap = utils.getEquivalenceMap()

    users = dac.getUserList()
    
    consumables = []
    for user in users:
        c = dac.getUserConsumables(user[1])
        consumables.extend(c)

    extra = readExtraRatings('Hippopottoman', 'extraRatings.txt')
    consumables.extend(extra)

    utils.normalizeSynonyms(consumables, itemMap)
    return consumables


def getItemConsumables(itemNumber, consumables):
    return [x for x in consumables if x.itemNumber == itemNumber and x.worthIt is not None]


def rating(consumable):
    if consumable.worthIt:
        return 1.0
    else:
        return 0.0

def averageItemRating(consumables):
    if len(consumables) == 0:
        return 0
    else:
        total = 0.0
        for c in consumables:
            total += rating(c)
        return total/float(len(consumables))

    

def correlationCompareTwoItems(itemNumber1, itemNumber2, consumables, cachedConsumables={}):
    if cachedConsumables.has_key(itemNumber1):
        consumables1 = cachedConsumables[itemNumber1]
    else:
        consumables1 = getItemConsumables(itemNumber1, consumables)
        cachedConsumables[itemNumber1] = consumables1

    if cachedConsumables.has_key(itemNumber2):
        consumables2 = cachedConsumables[itemNumber2]
    else:
        consumables2 = getItemConsumables(itemNumber2, consumables)
        cachedConsumables[itemNumber2] = consumables2

    averageItem1Rating = averageItemRating(cachedConsumables1)
    averageItem2Rating = averageItemRating(cachedConsumables2)

    item1Readers = [x.userName for x in cachedConsumables1]
    item2Readers = [x.userName for x in cachedConsumables2]
    
    
    
    return 0

def cosineCompareTwoItems(itemNumber1, itemNumber2, consumables, cachedConsumables={}):
    if cachedConsumables.has_key(itemNumber1):
        consumables1 = cachedConsumables[itemNumber1]
    else:
        consumables1 = getItemConsumables(itemNumber1, consumables)
        cachedConsumables[itemNumber1] = consumables1

    if cachedConsumables.has_key(itemNumber2):
        consumables2 = cachedConsumables[itemNumber2]
    else:
        consumables2 = getItemConsumables(itemNumber2, consumables)
        cachedConsumables[itemNumber2] = consumables2

    length = 0
    score = 0.0

    for c1 in consumables1:
        u1 = c1.userName
        for c2 in consumables2:
            if c2.userName == u1:
                # match
                length += 1
                if c1.worthIt == c2.worthIt:
                    score += 1.0
                else:
                    score -= 1.0
                break
    if length > 0:
        return (score/length, length)
    else:
        return (0, 0)
        


def main(args=None):
    if args == None:
        args = sys.argv[1:]
        
        consumables = readConsumables()
        allItems = {}
        numberOfReaders = {}
        for c in consumables:
            allItems[c.itemNumber] = c.itemTitle
            numberOfReaders[c.itemNumber] = numberOfReaders.get(c.itemNumber, 0) + 1


        print 'read', len(consumables), 'consumable records'
        results = []
        itemNumbers = allItems.keys()

        print 'there are', len(itemNumbers), 'items'

        # prune to items read by more than one person
        itemNumbers = [x for x in itemNumbers if numberOfReaders[x] >= minReaders]

        print 'pruned to', len(itemNumbers), 'items'

        for i in range(len(itemNumbers)):
            print 'checking out', allItems[itemNumbers[i]]
            for j in range(i+i, len(itemNumbers)):
                similarity = cosineCompareTwoItems(itemNumbers[i], itemNumbers[j], consumables)
                if similarity[0] > 0 and similarity[1] >= minReaders:                        
                    results.append((similarity[0], similarity[1], allItems[itemNumbers[i]], allItems[itemNumbers[j]]))
        results.sort()
        results.reverse()
        o = file('similarities.txt', 'wb')
        for r in results:
            o.write(str(r) + '\n')
                
    return 0


if __name__ == '__main__':
    sys.exit(main())

